package cn.fboost.mtos.util;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.concurrent.atomic.AtomicBoolean;

@Slf4j
@Component
public class WeChatUtil {
    private final ConfigUtil configUtil;

    private static Config wechatPayConfig;
    private static WxMaService wxMaService;

    public WeChatUtil(ConfigUtil configUtil) {
        this.configUtil = configUtil;
    }

    /**
     * 获取微信支付Config
     *
     * @return {@link Config}
     * @see <a href="https://github.com/wechatpay-apiv3/wechatpay-java#%E8%87%AA%E5%8A%A8%E6%9B%B4%E6%96%B0%E5%BE%AE%E4%BF%A1%E6%94%AF%E4%BB%98%E5%B9%B3%E5%8F%B0%E8%AF%81%E4%B9%A6">自动更新微信支付平台证书</a>
     */
    public Config getPayConfig() {
        // 必须为单例，如果为null则尝试初始化
        if (wechatPayConfig == null) {
            // 配置项检查
            AtomicBoolean disabledLoad = new AtomicBoolean(false);
            HashMap<String, String> c = configUtil.getPrefixConfig("wechat.pay").entrySet().stream().collect(HashMap::new, (m, e) -> {
                if (e.getValue() == null) {
                    disabledLoad.set(true);
                    m.put(e.getKey(), null);

                    log.error("微信支付未配置，配置项：{}", e.getKey());
                } else {
                    String val = String.valueOf(e.getValue());
                    if (val.length() == 0) {
                        disabledLoad.set(true);

                        log.error("微信支付未配置，配置项：{}", e.getKey());
                    }

                    m.put(e.getKey(), val);
                }
            }, HashMap::putAll);

            // 如果有配置项为空，则不加载
            if (disabledLoad.get()) {
                return null;
            }

            wechatPayConfig = new RSAAutoCertificateConfig.Builder()
                    .merchantId(c.get("wechat.pay.merchant-id"))
                    .privateKey(c.get("wechat.pay.private-key"))
                    .merchantSerialNumber(c.get("wechat.pay.cert-sn"))
                    .apiV3Key(c.get("wechat.pay.api-key-v3"))
                    .build();
        }

        return wechatPayConfig;
    }

    /**
     * 获取微信小程序服务单例对象
     *
     * @return {@link WxMaService}
     */
    public WxMaService getWxMaService() {
        HashMap<String, String> config = configUtil.getPrefixConfig("wechat.mini-program").entrySet()
                .stream()
                .collect(HashMap::new, (m, e) -> {
                    m.put(e.getKey(), e.getValue() != null ? String.valueOf(e.getValue()) : null);
                }, HashMap::putAll);

        WxMaDefaultConfigImpl wxConfig = new WxMaDefaultConfigImpl();
        wxConfig.setAppid(String.valueOf(config.get("wechat.mini-program.appid")));
        wxConfig.setSecret(String.valueOf(config.get("wechat.mini-program.secret")));
        wxConfig.setToken(String.valueOf(config.get("wechat.mini-program.token")));
        wxConfig.setAesKey(String.valueOf(config.get("wechat.mini-program.aes_key")));
        wxConfig.setMsgDataFormat(String.valueOf(config.get("wechat.mini-program.data-format")));
        if (wxMaService == null) {
            WxMaService service = new WxMaServiceImpl();
            service.setWxMaConfig(wxConfig);

            wxMaService = service;
        } else {
            wxMaService.setWxMaConfig(wxConfig);
        }

        return wxMaService;
    }
}
